package ntd.util.frame.action.ai;

import cn.hutool.core.collection.CollStreamUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.db.Db;
import cn.hutool.db.Entity;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import cn.hutool.log.StaticLog;
import com.c.Constant;
import com.modular.extra.ai.FactoryAiOpt;
import ntd.action.ActionAbs;
import ntd.action.bo.ActionInfo;
import ntd.action.bo.ActionOutBo;
import ntd.util.config.common.bo.PageBO;
import ntd.util.config.common.exception.ComException;
import ntd.util.frame.action.ActionPage;
import ntd.util.frame.action.database.tool.ToolDb;
import ntd.util.frame.data.factory.FactoryData;
import ntd.util.frame.javacv.action.bean.VisionModelDo;
import ntd.util.frame.javacv.tool.ToolAiUserSites;

import java.sql.SQLException;
import java.util.List;
import java.util.Map;

public class ActionAiReport extends ActionAbs {

    private static Map<String, String> dataFormatMap = MapUtil.ofEntries(MapUtil.entry("day", "%Y%m%d"), MapUtil.entry("month", "%Y%m"), MapUtil.entry("year", "%Y"));

    @Override
    public ActionInfo info() {
        return new ActionInfo("AI报表", "action-ai-vision-report", new ActionAiReport());
    }

    @Override
    public ActionOutBo handle() {
        // 执行逻辑,day、month、year
        String type = actionInBo.getDataCode();
        String mn = actionInBo.getParamStr("mn");
        String timeStr = actionInBo.getParamStr("timeStr");

        if (StrUtil.isEmpty(type)) {
            throw new ComException("参数有误");
        }

        //数据库
        Db use = Db.use(FactoryData.dataSource("272ab1b9c5cc4ea2b76302238247284c"));

        List<Entity> result = null;
        int length = 0;
        try {
            String limitSql = ToolDb.pageSql(ActionPage.getPage(actionInBo), ActionPage.getSize(actionInBo));
            result = use.query(timeWhere(type, timeStr, mn)+limitSql);
            length = use.query(timeWhereTotal(type, timeStr, mn)).size();
        } catch (SQLException e) {
            StaticLog.error(e, "[AI][报表][{}]失败...");
        }

        Map<String, List<Entity>> groupByKey = CollStreamUtil.groupByKey(result, entity -> entity.getStr("siteMn") + Constant.DIVISION + entity.getStr("time"));

        JSONArray array = JSONUtil.createArray();
        for (Map.Entry<String, List<Entity>> entry : groupByKey.entrySet()) {
            String[] split = entry.getKey().split(Constant.DIVISION);
                JSONObject obj = JSONUtil.createObj();
                obj.set("mn", split[0]);
                obj.set("time", split[1]);
                for (VisionModelDo visionModelDo : FactoryAiOpt.OPT_VISION_MODEL.cacheListAll()) {
                    Entity tempEntity = CollectionUtil.findOne(entry.getValue(), entity -> visionModelDo.getCode().equals(entity.get("ai_mode_type")));
                    obj.set(visionModelDo.getName(), "0");
                    if (ObjectUtil.isNotNull(tempEntity)) {
                        obj.set(visionModelDo.getName(), tempEntity.getStr("num"));
                    }
                }
                array.put(obj);

        }

        PageBO<Object> objectPageBO = new PageBO<>();
        objectPageBO.setTotal(length);
        objectPageBO.setRecords(array);

        return new ActionOutBo(objectPageBO);
    }

    private static String timeWhere(String type, String timeStr, String mn, String sql) {
        String dataFormat = dataFormatMap.get(type);
        String whereTimeStr = " where 1 = 1";
        if (StrUtil.isNotBlank(timeStr)) {
            whereTimeStr += StrUtil.format(" and DATE_FORMAT(analytics_time, '{}') = {}", dataFormat, timeStrBuild(type, timeStr));
        }
        if (StrUtil.isNotBlank(mn)) {
            whereTimeStr += StrUtil.format(" and siteMn = {}", mn);
        }else {//查权限内的全部mn
            if (!ToolAiUserSites.getCurrMns().isEmpty()){
                whereTimeStr += StrUtil.format(" and siteMn in ({})", StrUtil.concat(true,"'",StrUtil.join("','", ToolAiUserSites.getCurrMns()),"'"));
            }
        }
        return StrUtil.format(sql, dataFormat, whereTimeStr, dataFormat);
    }

    private static String timeWhere(String type, String timeStr, String mn) {
        String sql = "select siteMn, DATE_FORMAT(analytics_time, '{}') as time, ai_mode_type, count(*) as num from airesult {} group by siteMn, ai_mode_type, DATE_FORMAT(analytics_time, '{}')";
        return timeWhere(type, timeStr, mn, sql);
    }

    private static String timeWhereTotal(String type, String timeStr, String mn) {
        String sql = "select siteMn, DATE_FORMAT(analytics_time, '{}') as time, count(*) as num from airesult {} group by siteMn, DATE_FORMAT(analytics_time, '{}')";
        return timeWhere(type, timeStr, mn, sql);
    }

    private static String timeStrBuild(String type, String timeStr) {
        if (StrUtil.isBlank(timeStr)) {
            return null;
        }
        switch (type) {
            case "day": return StrUtil.sub(timeStr, 0, 8);
            case "month": return StrUtil.sub(timeStr, 0, 6);
            case "year": return StrUtil.sub(timeStr, 0, 4);
            default: throw new ComException("报表类型不被支持，请联系管理员...");
        }
    }
}
